﻿using System.Collections.Generic;
using System.Linq;
using System;

namespace XEnamel
{
	public static class StringExtensions
	{
		private const char LISTITEM_DELIMITER = ',';
		private const char STRING_DELIMITER = '\'';
		private const char EXPRESSION_START = '{';
		private const char EXPRESSION_END = '}';

		/// <summary>
		/// Splits a string into individual arguments, taking strings into account.
		/// </summary>
		public static IEnumerable<string> SplitEx(this string @this)
		{
			var list = new List<string>();

			list.Add(string.Empty);
			for (int index = 0; index < @this.Length; index++)
			{
				if (@this[index] == EXPRESSION_START)
				{
					list[list.Count() - 1] += @this[index];
					while (true)
					{
						index++;
						if (@this[index] == STRING_DELIMITER)
						{
							while (true)
							{
								list[list.Count() - 1] += @this[index];
								if (@this[index] == '\\')
								{
									index++;
									list[list.Count() - 1] += @this[index];
								}
								index++;
								if (@this[index] == STRING_DELIMITER)
								{
									break;
								}
							}
							list[list.Count() - 1] += @this[index];
						}
						else if (@this[index] == EXPRESSION_END)
						{
							list[list.Count() - 1] += @this[index];
							break;
						}
						else
						{
							list[list.Count() - 1] += @this[index];
						}
					}
				}
				else if (@this[index] == LISTITEM_DELIMITER)
				{
					list.Add(string.Empty);
				}
				else
				{
					throw new InvalidOperationException(string.Format("Unexpected character found at {0}: '{1}'", index, @this[index]));
				}
			}
			if ((list.Count() == 1) && (list[0] == string.Empty))
			{
				return null;
			}
			return list;
		}

		public static IEnumerable<string> SplitEx_old(this string @this)
		{
			var list = new List<string>();

			list.Add(string.Empty);
			for (int index = 0; index < @this.Length; index++)
			{
				if (@this[index] == STRING_DELIMITER)
				{
					while (true)
					{
						list[list.Count() - 1] += @this[index];
						if (@this[index] == '\\')
						{
							index++;
							list[list.Count() - 1] += @this[index];
						}
						index++;
						if (@this[index] == STRING_DELIMITER)
						{
							break;
						}
					}
					list[list.Count() - 1] += @this[index];
				}
				//else if (@this[index] == EXPRESSION_START)
				//{
				//    while (true)
				//    {
				//        if (@this[index] == EXPRESSION_END)
				//        {
				//            break;
				//        }
				//        list[list.Count() - 1] += @this[index];
				//        index++;
				//    }
				//    list[list.Count() - 1] += @this[index];
				//}
				else if (@this[index] == LISTITEM_DELIMITER)
				{
					list.Add(string.Empty);
				}
				else
				{
					list[list.Count() - 1] += @this[index];
				}
			}
			if ((list.Count() == 1) && (list[0] == string.Empty))
			{
				return null;
			}
			return list;
		}
	}
}